/*
 ************************************************************************************************
 *                                                                                              *
 *  OSA cooperative RTOS for Microchip PIC-controllers: PIC10/12/16/18/24/dsPIC                 *
 *                                                                                              *
 *  URL:        http://wiki.pic24.ru/doku.php/en/osa/ref/intro                                  *
 *              http://picosa.narod.ru                                                          *
 *                                                                                              *
 *----------------------------------------------------------------------------------------------*
 *                                                                                              *
 *  File:       osa_smsg.h                                                                      *
 *                                                                                              *
 *  Compilers:  HT-PICC STD                                                                     *
 *              HT-PICC18 STD                                                                   *
 *              Microchip C18                                                                   *
 *              Microchip C30                                                                   *
 *                                                                                              *
 *  Programmer: Timofeev Victor                                                                 *
 *              osa@pic24.ru, testerplus@mail.ru                                                *
 *                                                                                              *
 *  Definition: Services for work with simple messages                                          *
 *                                                                                              *
 *                                                                                              *
 ************************************************************************************************
 */





/************************************************************************************************
 *                                                                                              *
 *                              S I M P L E     M E S S A G E S                                 *
 *                                                                                              *
 ************************************************************************************************/



#if defined(OS_ENABLE_INT_SMSG) && (OS_SMSG_SIZE != 1)

    #define __OS_SMSG_DI()       {_OS_temp = OS_DI();}
    #define __OS_SMSG_RI()       {OS_RI(_OS_temp);}

#else

    #define __OS_SMSG_DI()
    #define __OS_SMSG_RI()

#endif


#if !defined(OS_ENABLE_INT_SMSG) || (OS_SMSG_SIZE == 1)
    // Check for message exists
    #define OS_SMsg_Check(smsg)       (smsg != (OST_SMSG)0)

    // Check for message is free
    #define OS_IsSMsgFree(smsg)       (smsg == (OST_SMSG)0)
#else
    bit _OS_SMsg_Check(OST_SMSG*);

    // Check for message exists
    #define OS_SMsg_Check(smsg)       _OS_SMsg_Check(&(smsg))

    // Check for message is free
    #define OS_IsSMsgFree(smsg)      (!_OS_CkeckSMsg(&(smsg)))
#endif



//------------------------------------------------------------------------------
// Internal macro: Clear message (internal system service)
#define _OS_MakeSMsgFree(smsg)         smsg = (OST_SMSG)0


//------------------------------------------------------------------------------
// Create simple message

#define OS_SMsg_Create(smsg)                                            \
    {                                                                   \
        __OS_SMSG_DI();                                                 \
        _OS_MakeSMsgFree(smsg);                                         \
        __OS_SMSG_RI();                                                 \
    }                                                                   \


//------------------------------------------------------------------------------
// Send simple message. If message already exists then wait when it became free.

#define OS_SMsg_Send(smsg, message)                                     \
    {                                                                   \
        if (OS_SMsg_Check(smsg))                                        \
            _OS_WAIT_EVENT(OS_IsSMsgFree(smsg));                        \
        __OS_SMSG_DI();                                                 \
        smsg = (OST_SMSG) message;                                      \
        __OS_SMSG_RI();                                                 \
    }

//------------------------------------------------------------------------------
// Send simple message. If message already exists then it will be overwritten.

#define OS_SMsg_Send_Now(smsg, message)                                 \
    {                                                                   \
        OS_Flags.bEventError = 0;                                       \
        if (OS_SMsg_Check(smsg)) OS_Flags.bEventError = 1;              \
        __OS_SMSG_DI();                                                 \
        smsg = (OST_SMSG) message;                                      \
        __OS_SMSG_RI();                                                 \
    }


//------------------------------------------------------------------------------
// Send simple message. If message already exists then wait when it became free.
// Exit if timeout expired.

#define OS_SMsg_Send_TO(smsg, message, timeout)                     \
    {                                                               \
        OS_Flags.bTimeout = 0;                                      \
        if (OS_SMsg_Check(smsg))                                    \
        {                                                           \
            _OS_WAIT_EVENT_TIMEOUT(OS_IsSMsgFree(smsg), timeout);   \
        }                                                           \
        if (!OS_IsTimeout()) {                                      \
            __OS_SMSG_DI();                                         \
            smsg = (OST_SMSG) message;                              \
            __OS_SMSG_RI();                                         \
        }                                                           \
    }


//------------------------------------------------------------------------------
// Wait for simple message. After accepting simple message is cleared.

#define OS_SMsg_Wait(smsg, os_smsg_type_var)                        \
    {                                                               \
        _OS_WAIT_EVENT(OS_SMsg_Check(smsg));                        \
        OS_SMsg_Accept(smsg, os_smsg_type_var);                     \
    }


//------------------------------------------------------------------------------
// Wait for simple message. After accepting simple message is cleared.
// Exit if timeout expired.

#define OS_SMsg_Wait_TO(smsg, os_smsg_type_var, timeout)            \
    {                                                               \
        _OS_WAIT_EVENT_TIMEOUT(OS_SMsg_Check(smsg), timeout);       \
        if (!OS_IsTimeout()) {                                      \
            OS_SMsg_Accept(smsg, os_smsg_type_var);                 \
        }                                                           \
    }

//------------------------------------------------------------------------------
// Accept existing simple message. After accepting message is cleared.

#define OS_SMsg_Accept(smsg, os_smsg_type_var)                      \
    {                                                               \
        __OS_SMSG_DI();                                             \
        os_smsg_type_var = smsg;                                    \
        _OS_MakeSMsgFree(smsg);                                     \
        __OS_SMSG_RI();                                             \
    }





//------------------------------------------------------------------------------
#ifdef OS_ENABLE_INT_SMSG
//------------------------------------------------------------------------------

// Send simple message from interrupt. If message already exists then it will be overwritten.
#define OS_SMsg_Send_I(smsg, message)                               \
    {                                                               \
        OS_Flags.bEventError = 0;                                   \
        if (OS_SMsg_Check(smsg)) OS_Flags.bEventError = 1;          \
        smsg = (OST_SMSG) message;                                  \
    }


//------------------------------------------------------------------------------
#endif
//------------------------------------------------------------------------------

















